﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;
using EPiServer;
using EPiServer.Core;

namespace EPiBoost.Core.Infrastructure
{
	public class HttpExceptionHandler
	{
		public string ErrorPage404Url { get; set; }
		public string ErrorPage500Url { get; set; }


		public static readonly List<int> ErrorHttpStatusCodes = new List<int>()
			{
				400, 404 , 500/*, 501, 502, 503*/
			};

		public static bool StatusCodeIsException(int statusCode)
		{
			return ErrorHttpStatusCodes.Contains(statusCode);
		}

		public static bool CustomErrorsEnabled
		{
			get
			{
				var config = WebConfigurationManager.OpenWebConfiguration("~");
				CustomErrorsSection section = (CustomErrorsSection) config.GetSection("system.web/customErrors");

				if (section != null)
				{
					return section.Mode == CustomErrorsMode.On || (section.Mode == CustomErrorsMode.RemoteOnly && IsRemoteUser);
				}
				return false;
			}
		}

		private static bool IsRemoteUser
		{
			get
			{
				var host = HttpContext.Current.Request.UserHostAddress;
				return !(host == "127.0.0.1" || host == "::1");
			}
		}


		public void HandleStatusCode(HttpResponse response, int statusCode = -1)
		{
			if (IsUtilOrCmsRequest())
			{
				return;
			}
			if (HttpContext.Current.Request.QueryString["epi-error-internal"] != null)
			{
				return;
			}

			statusCode = statusCode == -1 ? response.StatusCode : statusCode;
			
			switch(statusCode)
			{
				case 404:
					CustomRedirects.CustomRedirectHandler.Current.TryRedirect();
					SetResponse(response, ErrorPage404Url, statusCode); 
					break;
				case 500:
					if (CustomErrorsEnabled)
					{
						SetResponse(response, ErrorPage500Url, statusCode); 
					}
					break;
				default:
					break;
			}
		}

		private bool IsUtilOrCmsRequest()
		{
			if (HttpContext.Current != null)
			{
				var requestUrl = HttpContext.Current.Request.Url;
				var uiUrl = EPiServer.Configuration.Settings.Instance.UIUrl;
				var utilUrl = EPiServer.Configuration.Settings.Instance.UtilUrl;

				if (requestUrl.ToString().ToLower().Contains(uiUrl.ToString().TrimStart('~'))
						|| requestUrl.ToString().ToLower().Contains(utilUrl.ToString().TrimStart('~')))
				{
					return true;
				}

			}
			return false;
		}

		public void SetResponse(HttpResponse response, string url, int statusCode)
		{
			if(!string.IsNullOrEmpty(url))
			{
				if (url.StartsWith("~/"))
				{
					url = System.Web.HttpContext.Current.Server.MapPath(url);
				}

				if(url.StartsWith("/"))
				{
					var uri = new UrlBuilder(HttpContext.Current.Request.Url);
					uri.Path = url;
				  if (uri.QueryCollection == null)
				  {
					  uri.QueryCollection = new NameValueCollection();
				  }
					uri.QueryCollection.Add("epi-error-internal","true");
					url = uri.ToString();
					 
				}

				var newBody = "Error Page could not be loaded from " + url;
				try
				{
					newBody = Helpers.ResponseHelper.GetResponseFromUrl(url);
				}
				catch (Exception ex)
				{
					
				}
				response.ClearContent();
				response.Write(newBody);

				response.StatusCode = 200;
				response.TrySkipIisCustomErrors = true;
				response.StatusCode = statusCode;
			}
		}

		
	}
}
